'use strict';

const BaseController = require('../../core/base_controller');
const xlsx = require('xlsx');
const path = require('path');

class PositionController extends BaseController {
  // 获取岗位列表
  async index() {
    const { ctx } = this;
    const { name } = ctx.query;

    // 构建查询条件
    const where = {};
    if (name) {
      where.name = {
        [ctx.model.Sequelize.Op.like]: `%${name}%`
      };
    }

    // 只查询顶级岗位
    where.parent_id = null;

    const list = await ctx.model.Position.findAll({
      where,
      include: [
        {
          model: ctx.model.Position,
          as: 'children',
          include: [
            {
              model: ctx.model.Position,
              as: 'children'
            }
          ]
        }
      ],
      order: [
        ['sort', 'ASC'],
        ['created_at', 'DESC'],
        [{ model: ctx.model.Position, as: 'children' }, 'sort', 'ASC'],
        [{ model: ctx.model.Position, as: 'children' }, { model: ctx.model.Position, as: 'children' }, 'sort', 'ASC']
      ]
    });

    this.success(list);
  }

  // 创建岗位
  async create() {
    const { ctx } = this;
    const rules = {
      name: { type: 'string', required: true },
      parent_id: { type: 'integer', required: false },
      description: { type: 'string', required: false },
      sort: { type: 'integer', required: false },
      icon: { type: 'string', required: false },
    };

    try {
      ctx.validate(rules);
    } catch (err) {
      ctx.throw(400, '参数错误');
    }

    // 如果有父级ID，检查父级是否存在
    if (ctx.request.body.parent_id) {
      const parent = await ctx.model.Position.findByPk(ctx.request.body.parent_id);
      if (!parent) {
        ctx.throw(400, '父级岗位不存在');
      }
    }

    const position = await ctx.model.Position.create(ctx.request.body);
    this.success(position);
  }

  // 更新岗位
  async update() {
    const { ctx } = this;
    const position = await ctx.model.Position.findByPk(ctx.params.id);

    if (!position) {
      ctx.throw(404, '岗位不存在');
    }

    const rules = {
      name: { type: 'string', required: false },
      parent_id: { type: 'integer', required: false },
      description: { type: 'string', required: false },
      sort: { type: 'integer', required: false },
      icon: { type: 'string', required: false },
    };

    try {
      ctx.validate(rules);
    } catch (err) {
      ctx.throw(400, '参数错误');
    }
    // 如果要修改父级，检查父级是否存在
    if (ctx.request.body.parent_id) {
      const parent = await ctx.model.Position.findByPk(ctx.request.body.parent_id);
      if (!parent) {
        ctx.throw(400, '父级岗位不存在');
      }
      // 不能将自己设为自己的父级
      if (ctx.request.body.parent_id === position.id) {
        ctx.throw(400, '不能将岗位设为自己的父级');
      }
    }

    await position.update(ctx.request.body);
    this.success(position);
  }

  // 删除岗位
  async destroy() {
    const { ctx } = this;
    const position = await ctx.model.Position.findByPk(ctx.params.id);

    if (!position) {
      ctx.throw(404, '岗位不存在');
    }

    await position.destroy();
    this.success(null, '删除成功');
  }

  // 获取单个岗位
  async show() {
    const { ctx } = this;
    const position = await ctx.model.Position.findByPk(ctx.params.id);

    if (!position) {
      ctx.throw(404, '岗位不存在');
    }

    this.success(position);
  }

  // 修改岗位状态
  async updateStatus() {
    const { ctx } = this;
    const { id } = ctx.params;
    const { status } = ctx.request.body;

    const rules = {
      status: {
        type: 'enum',
        values: [0, 1, true, false],
        required: true,
        message: '状态值错误',
      },
    };

    try {
      ctx.validate(rules);
    } catch (err) {
      const errors = err.errors.map(error => rules[error.field].message).map(el=>el.string).join();
      ctx.throw(400, errors);
    }

    const position = await ctx.model.Position.findByPk(id);
    if (!position) {
      ctx.throw(404, '岗位不存在');
    }

    await position.update({ status });
    this.success(null, '状态更新成功');
  }

  // 导入岗位
  async import() {
    const { ctx } = this;
    const file = ctx.request.files[0];
    if (!file) ctx.throw(400, '请上传Excel文件');

    const fileExt = path.extname(file.filename).toLowerCase();
    if (fileExt !== '.xlsx' && fileExt !== '.xls') {
      ctx.throw(400, '只支持.xlsx或.xls格式的Excel文件');
    }

    try {
      const workbook = xlsx.readFile(file.filepath);
      const worksheet = workbook.Sheets[workbook.SheetNames[0]];
      const data = xlsx.utils.sheet_to_json(worksheet);

      if (data.length === 0) {
        ctx.throw(400, 'Excel文件内容为空');
      }

      if (!data[0]['岗位名称']) {
        ctx.throw(400, 'Excel文件格式错误，必须包含"岗位名称"和"岗位编码"列');
      }

      const positions = data.map((row, index) => ({
        name: row['岗位名称'],
        description: row['描述'] || null,
        sort: row['排序'] || index,
        icon: row['图标'] || null
      }));

      await ctx.model.Position.bulkCreate(positions);
      this.success(null, `成功导入${positions.length}条数据`);
    } catch (error) {
      ctx.throw(500, '导入失败：' + error.message);
    } finally {
      await ctx.cleanupRequestFiles();
    }
  }

  // 批量更新排序
  async updateSort() {
    const { ctx } = this;
    const { items } = ctx.request.body;

    // 验证输入参数
    if (!Array.isArray(items)) {
      ctx.throw(400, '参数错误：items必须是数组');
    }

    if (items.length === 0) {
      ctx.throw(400, '参数错误：items不能为空数组');
    }

    // 验证每个item的格式
    items.forEach((item, index) => {
      if (!item.id || typeof item.sort !== 'number') {
        ctx.throw(400, `参数错误：第${index + 1}项数据格式不正确，需要包含id和sort字段`);
      }
    });

    try {
      // 使用循环逐个更新
      for (const item of items) {
        await ctx.model.Position.update(
          { sort: item.sort },
          { where: { id: item.id } }
        );
      }

      this.success(null, '排序更新成功');
    } catch (error) {
      ctx.throw(500, '更新排序失败：' + error.message);
    }
  }
}

module.exports = PositionController;
